/**
 * @file sdl_show_bmp.cpp
 * @author 逆流 (1171267147@qq.com)
 * @brief 加载一张bmp格式图片并在窗口中显示
 * @version 0.1
 * @date 2024-06-12
 *
 * @copyright Copyright (c) 2024.
 * @ref
 * https://github.com/Twinklebear/TwinklebearDev-Lessons/blob/master/Lesson2/src/main.cpp
 *
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2024-06-12 <td>V0.1    <td>逆流     <td>实现bmp图像加载和显示
 * </table>
 */
#include <SDL2/SDL.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_surface.h>
#include <SDL_rect.h>

#include <exception>
#include <iostream>
#include <stdexcept>
#include <string>

#define USE_SDL2_IMAGE_LIB 1
#ifdef USE_SDL2_IMAGE_LIB
#include <SDL2/SDL_image.h>
#endif

#include "env.h"

int main(int argc, char** argv) {
    (void)argc;
    (void)argv;
    int return_code = 0;

    SDL_Window*   window{nullptr};
    SDL_Renderer* renderer{nullptr};
    SDL_Surface*  bmp{nullptr};
    SDL_Texture*  texture{nullptr};

    auto bmp_file = kResourcesDir + "background.bmp";

    try {
        if (SDL_Init(SDL_INIT_VIDEO) != 0) {
            throw std::runtime_error("SDL_Init failed");
        }

        window =
            SDL_CreateWindow("SDL2 Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
        if (window == nullptr) {
            throw std::runtime_error("SDL_CreateWindow failed");
        }

        renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
        if (renderer == nullptr) {
            throw std::runtime_error("SDL_CreateRenderer failed");
        }

#ifdef USE_SDL2_IMAGE_LIB
        texture = IMG_LoadTexture(renderer, bmp_file.c_str());
        if (texture == nullptr) {
            throw std::runtime_error("IMG_LoadTexture failed");
        }
#else
        // 将bmp图片加载到Surface中
        bmp = SDL_LoadBMP(BMP_PATH.c_str());
        if (bmp == nullptr) throw runtime_error("SDL_LoadBMP failed");

        // 将Surface转化为Texture
        texture = SDL_CreateTextureFromSurface(renderer, bmp);
        SDL_FreeSurface(bmp);  // bmp不再需要，可以释放掉
        bmp = nullptr;
        if (texture == nullptr) throw runtime_error("SDL_CreateTextureFromSurface failed");
#endif

        SDL_Rect window_rect  = {0, 0, 640, 480};
        SDL_Rect texture_rect = {0, 0, 0, 0};

        // 查询texture的长宽属性
        SDL_QueryTexture(texture, nullptr, nullptr, &texture_rect.w, &texture_rect.h);

        // std::cout << "texture size = (" << texture_rect.w << ", "
        //           << texture_rect.h << ")" << std::endl;

        window_rect.w = window_rect.w > texture_rect.w ? texture_rect.w : window_rect.w;
        window_rect.h = window_rect.h > texture_rect.h ? texture_rect.h : window_rect.h;

        for (int i = 0; i < 3; ++i) {
            SDL_RenderClear(renderer);

            // 将texture拷贝到窗口中，rect指针都为nullptr，表示用texture铺满整个窗口
            SDL_RenderCopy(renderer, texture, &texture_rect, &window_rect);
            SDL_RenderPresent(renderer);
            SDL_Delay(5000);
        }
    } catch (std::exception& e) {
        std::cerr << e.what() << '\n';
        return_code = -1;
    }

    if (texture != nullptr) {
        SDL_DestroyTexture(texture);
    }
    if (bmp != nullptr) {
        SDL_FreeSurface(bmp);
    }
    if (renderer != nullptr) {
        SDL_DestroyRenderer(renderer);
    }
    if (window != nullptr) {
        SDL_DestroyWindow(window);
    }
    SDL_Quit();

    return return_code;
}
